package musicserver;

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

import javax.jmdns.JmDNS;
import javax.jmdns.ServiceInfo;

public class Server implements Runnable{
	public static final String SERVICE_TYPE = "MusicServer._tcp.local.";
	public static final String SERVICE_NAME = "Sean";
	public int SERVICE_PORT = 1577;
	public static MusicLibrary library;
	/**
	 * Accept this many connections.
	 */
	private int my_backlog = 5;

	/**
	 * The server socket.
	 */
	private ServerSocket my_serverSocket;
	private String art;
	private String alb;
	private String tra;
	private InetAddress inad;
	private int pt;
	private boolean playTrack;
	
	
	public Server() {
		try {
			library = new MusicLibrary();
			my_serverSocket = new ServerSocket(0, my_backlog);
			SERVICE_PORT = my_serverSocket.getLocalPort();
		} catch (IOException ioe) {
			ioe.printStackTrace();
			//try { my_serverSocket = new ServerSocket(++SERVICE_PORT, my_backlog);
            //} catch (IOException e) { e.printStackTrace(); }
		} catch (SecurityException se) {
			se.printStackTrace();
		}
	}

	public void listen() {
		while (true) {
			try {
				Socket socket = my_serverSocket.accept();
				BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				String input = in.readLine();
				Scanner inputScanner = new Scanner(input);
				inputScanner.useDelimiter(",");
				String methodName = inputScanner.next();
				System.out.println(methodName);
				if(methodName.equals("getArtistList")){
		           	ObjectOutputStream os = new ObjectOutputStream( new BufferedOutputStream(socket.getOutputStream()));
	            	os.writeObject(library.getArtistList());
	            	os.flush();
	            	os.close();
				} else if(methodName.equals("getAlbumList")){
					String arg0 = inputScanner.next();
		           	ObjectOutputStream os = new ObjectOutputStream( new BufferedOutputStream(socket.getOutputStream()));
	            	os.writeObject(library.getAlbumList(arg0));
	            	os.flush();
	            	os.close();
					
				} else if(methodName.equals("getTrackList")){
					String arg0 = inputScanner.next();
					String arg1 = inputScanner.next();
		           	ObjectOutputStream os = new ObjectOutputStream( new BufferedOutputStream(socket.getOutputStream()));
	            	os.writeObject(library.getTrackList(arg0, arg1));
	            	os.flush();
	            	os.close();
					
				} else if(methodName.equals("playTrack")){
					art = inputScanner.next();
					alb = inputScanner.next();
					tra = inputScanner.next();
					pt = socket.getPort();
					inad = socket.getInetAddress();
					playTrack = true;
					Thread t = new Thread(this);
					t.start();
	            	//playTrack(arg0, arg1, arg2,socket.getPort(),socket.getInetAddress());
	            	//System.exit(0);
				} else if(methodName.equals("searchArtist")){
					String arg0 = inputScanner.next();
					ObjectOutputStream os = new ObjectOutputStream( new BufferedOutputStream(socket.getOutputStream()));
	            	os.writeObject(library.searchArtist(arg0));
	            	os.flush();
	            	os.close();
				} 

				in.close();
				socket.close();
			} catch (IOException ioe) {
				ioe.printStackTrace();
			} catch (SecurityException se) {
				se.printStackTrace();
            }
		}

	}

	private void playTrack(String arg0, String arg1, String arg2, int port, InetAddress inetAddress)
	        throws IOException, InterruptedException {
		DatagramSocket socket = null;
		socket = new DatagramSocket();
		for (int i = 0; i < 120; i++) {
			byte[] buf = ("The Song is now Playing: " + i + "s").getBytes();
			DatagramPacket packet = new DatagramPacket(buf, buf.length, inetAddress, port);
			socket.send(packet);
			Thread.sleep(1000);
		}
		byte[] buf = ("The Song is now Finished:").getBytes();
		DatagramPacket packet = new DatagramPacket(buf, buf.length, inetAddress, port);
		socket.send(packet);
	}

	public static void main(String[] args) {
		JmDNS jmdns;
		Server serv = new Server();
		(new Thread(serv)).start();

		try {
			jmdns = JmDNS.create();
			ServiceInfo info = ServiceInfo.create(Server.SERVICE_TYPE, Server.SERVICE_NAME, serv.SERVICE_PORT, 0, 0, "Server_Type=Main_Server");
			jmdns.registerService(info);
			System.out.println("Registered Service as " + info);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void run() {
		
		System.out.println("Thread: "+Thread.currentThread().getId()+ " is starting.");
		if(playTrack){
			playTrack = false;
			try { playTrack(art, alb, tra, pt, inad);
            } catch (Exception e) { e.printStackTrace(); }
		}else{
			System.out.println("Thread: "+Thread.currentThread().getId()+ " will not finish!");
			listen();
		}
		System.out.println("Thread: "+Thread.currentThread().getId()+ " is finishing.");
		
	}
}
